package cn.gov.pbc.audit.util;

import java.io.IOException;
import java.text.SimpleDateFormat;

import org.apache.commons.lang3.StringUtils;
import org.codehaus.jackson.map.DeserializationConfig;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.SerializationConfig;
import org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion;
import org.codehaus.jackson.type.JavaType;
import org.codehaus.jackson.type.TypeReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 
 * @author 黄松祥
 *
 * 2018年3月28日 下午8:28:30
 */
public class JsonUtil {
	
	private static final Logger log = LoggerFactory.getLogger(JsonUtil.class);
	
	private static ObjectMapper objectMapper = new ObjectMapper();
	static {
		//对象的所有字段都序列化
		objectMapper.setSerializationInclusion(Inclusion.ALWAYS);
		//取消默认转化为timestamp形式
		objectMapper.configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS, false);
		//忽略空bean转化为json的异常
		objectMapper.configure(SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS, false);
		//所有的日期格式都统一为以下的样式，即yyyy-MM-dd HH:mm:ss
		objectMapper.setDateFormat(new SimpleDateFormat(DateTimeUtil.STANDARD_FORMAT));
		
		//忽略 在json字符串中存在，但是在java对象中不存在对应属性的情况。防止错误
        objectMapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES,false);
	}
	
	public static <T> String obj2String(T obj) {
		if(obj == null) {
			return null;
		};
		try {
			if(obj instanceof String) {
				return (String)obj;
			}
			return objectMapper.writeValueAsString(obj);
		} catch (IOException e) {
			log.warn("对象序列化失败", e);
			return null;
		}
	}
	
	@SuppressWarnings("unchecked")
	public static <T> T string2Obj(String str,Class<T> clazz){
        if(StringUtils.isEmpty(str) || clazz == null){
            return null;
        }
        try {
        	if(clazz.equals(String.class)) {
        		return (T)str;
        	}
        	return objectMapper.readValue(str, clazz);
        } catch (Exception e) {
            log.warn("对象反序列化失败",e);
            return null;
        }
    }
	
	@SuppressWarnings("unchecked")
	public static <T> T string2Obj(String str, TypeReference<T> typeReference){
        if(StringUtils.isEmpty(str) || typeReference == null){
            return null;
        }
        try {
            return (T)(typeReference.getType().equals(String.class)? str : objectMapper.readValue(str,typeReference));
        } catch (Exception e) {
        	log.warn("对象反序列化失败",e);
            return null;
        }
    }


    public static <T> T string2Obj(String str,Class<?> collectionClass,Class<?>... elementClasses){
        JavaType javaType = objectMapper.getTypeFactory().constructParametricType(collectionClass,elementClasses);
        try {
            return objectMapper.readValue(str,javaType);
        } catch (Exception e) {
        	log.warn("对象反序列化失败",e);
            return null;
        }
    }
}



























